﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

//using SH_VBoxLibrary;


namespace SH_VBoxVM_Service.Classes
{

    /// <summary>
    /// Interface for the VBoxCom Class
    /// </summary>
    public interface IVBoxCom
    {

        /// <summary>
        /// Start Virtual Machine from a saved state or even after an aborted state. 
        /// This currently will only start as a Headless VM.
        /// Further testing will determine if I would need to allow also the ability 
        /// to choose between Headless and Headfull.
        /// </summary>
        /// <param name="vmname">The actual name of the VM in the VBox Manager</param>
        void StartVM(string vmname);

        /// <summary>
        /// Saves the VM current state.
        /// This is an option for when the Host of the VM shutsdown.
        /// Note: Requires a minor change in Host's BIOS settings. Enabling Intel Virtualization Techonology property.
        /// </summary>
        /// <param name="vmname">The actual name of the VM in the VBox Manager</param>
        void SaveVMState(string vmname);

        /// <summary>
        /// Shutsdown the VM Gracefully without an abort state.
        /// This is an option for when the Host of the VM shutsdown.
        /// </summary>
        /// <param name="vmname">The actual name of the VM in the VBox Manager</param>
        void ShutdownVM(string vmname);

        /// <summary>
        /// Determines if the VM will automagically start after windows startup.
        /// Note: Use the VirtualMachine Class to determine this.
        /// This method should be part of another controller class that will handle the multiple instances of the VMs.
        /// </summary>
        /// <param name="vmname">The actual name of the VM in the VBox Manager.</param>
        /// <param name="isAutoStart">Bool: Determines if it will or will not start automagically.</param>
        void SetAutoStart(string vmname, bool isAutoStart);

        /// <summary>
        /// Sets the path where all the Virtual Machines are located for the Virtual Box Manager
        /// Usually its already set for your by the GUI Manager.
        /// WARNING: Shouldn't mess up with this method unless you know what you are doing.
        /// This can potentially mess up with the already working VMs
        /// Also Need to check if its still necessary to hold.
        /// </summary>
        /// <param name="directory">Path of the directory. i.e.: "C:/path/to/vm/directory"</param>
        void SetVBoxVirtualMachinesDirectory(string directory);
    }


    /// <summary>
    /// This Class communicates directly to the Command Promtp executable VBoxManage.exe
    /// Making the interaction between the user and VBox simpler.
    /// </summary>
    public class VBoxCom : IVBoxCom
    {

        private string CmdTxt;
        private string vboxmanagepath = "";

        public VBoxCom()
        {
            vboxmanagepath = string.Format(@"{0}\{1}",ConfigIO.vbmFolderPath,"vboxmanage.exe");     
        }

        ~VBoxCom()
        {
            CmdTxt = string.Empty;
        }

        //Note: the parameter WILL change to VirtualMachine Class for new version upgrades.
        public void StartVM(string vmname)
        {
            //First: make sure there is no saved state
            //Note: This is a temporary solution until VirtualBox's new update fixes the 'Resuming from SavedState' bug.
            CmdTxt = string.Format(@"vboxmanage discardstate {0}",vmname);
            ExecCommand(CmdTxt);

            //Now starting the VM, the type (headless,GUI) should be determined by the Virtual Machine class property.
            CmdTxt = string.Format(@"startvm --type {0} {1}","headless",vmname);
            ExecCommand(CmdTxt);
        }

       public void SaveVMState(string vmname)
       {

       }
     
       public void ShutdownVM(string vmname)
       {
           CmdTxt = string.Format(@"controlvm {0} poweroff",vmname);
           ExecCommand(CmdTxt);
       }
      

       public void SetAutoStart(string vmname, bool isAutoStart)
       {
           //Still dependant on my work flow and code design.
       }

       public void SetVBoxVirtualMachinesDirectory(string directory)
       {
           CmdTxt = string.Format(@"setproperty machinefolder {0}", directory);
           ExecCommand(CmdTxt);

       }


        /// <summary>
        /// Private Method, executes an Actual command from VBoxManage.exe.
        /// </summary>
        /// <param name="cmdline">CommandLine String that you would actually type in VBoxManage.exe</param>
        private void ExecCommand(string cmdline) 
        {
            //executes the commands directly into VBoxManage.exe
            Process pr = ApplicationLoader.CreateProcessAsUser(vboxmanagepath, cmdline);
     
        }


        /// <summary>
        /// Creates the Process but in a Suspended State.
        /// Requires UnFreezeThread Method from Application Loader to run these Processes.
        /// 
        /// ---
        /// @Deprecated : Idea didn't work as expected.
        /// </summary>
        /// <param name="cmdline"></param>
        private void ExecDelayedCommand(string cmdline)
        {
            //at the same time create the process that will PowerOff the Vm's but Suspended in Thread.
            //ApplicationLoader.CreateProcessAsUserSuspended(vboxmanagepath,cmdline);
        }
    }
}
